package initialize

import (
	"awesomeProject/user-web/global"
	"awesomeProject/user-web/proto"
	"awesomeProject/user-web/utils/otgrpc"
	"fmt"
	"github.com/hashicorp/consul/api"
	_ "github.com/mbobakov/grpc-consul-resolver"
	"github.com/opentracing/opentracing-go"
	"go.uber.org/zap"
	"google.golang.org/grpc"
)

// InitSrvConn 通过Consul来获取后端子服务的客户端
func InitSrvConn() {

	// 这里是实现连接到consul主机，并从主机上进行服务发现，获取后端主机连接

	ConsulInfo := global.ServerConfig.ConsulInfo
	// 维护负载均衡器
	consulParam := fmt.Sprintf("consul://%s:%d/%s?wait=%s&tag=%s",
		ConsulInfo.Host, ConsulInfo.Port, global.ServerConfig.UserSrvInfo.Name, "14s", "user")
	// 实现负载均衡  --- 取出一个链接
	connUser, err := grpc.Dial(consulParam, grpc.WithInsecure(),
		grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
		grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()))) // 实现RR轮转负载均衡

	if err != nil {
		zap.S().Fatal("通过Consul负载均衡获得连接失败：", zap.Error(err))
		return
	}
	global.UserSrvClient = proto.NewUserClient(connUser)

}

// InitSrvConn_Old 结合配置文件实现
func InitSrvConn_Old() {
	// 3.从Consul注册中心中获取一下用户子服务的ip和端口号
	cfg := api.DefaultConfig()
	ConsulInfo := global.ServerConfig.ConsulInfo
	cfg.Address = fmt.Sprintf("%s:%d", ConsulInfo.Host, ConsulInfo.Port) // consul的地址

	clientConsul, err := api.NewClient(cfg)
	if err != nil {
		panic(err)
	}

	serviceFilter := fmt.Sprintf("Service == \"%s\"", global.ServerConfig.UserSrvInfo.Name)

	data, err := clientConsul.Agent().ServicesWithFilter(serviceFilter) // 通过Consul的键值对来进行过滤
	if err != nil {
		panic(err)
	}

	// 4.进行负载均衡提取一个
	var userHost string
	var userPort int
	for _, val := range data {
		userPort = val.Port
		userHost = val.Address
	}

	// 4.拨号连接用户grpc服务

	zap.S().Infof(fmt.Sprintf("用户子服务，ip: %s, userPort: %s", userHost, userPort))
	// 发起链接获取数据

	userConn, err := grpc.Dial(fmt.Sprintf("%s:%d", userHost, userPort), grpc.WithInsecure())
	if err != nil {
		zap.S().Errorf("[GetUserList]获取grpc链接失败: %v", err.Error())
	}

	// 但是会有问题！！！ 服务下线怎么处理
	// 最后将userConn给我们全局的变量
	global.UserSrvClient = proto.NewUserClient(userConn)
}
